using System;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using Aluetjen.EmailService.Domain.Infrastructure;
using StructureMap;
using StructureMap.Pipeline;

namespace Aluetjen.EmailService.Infrastructure
{
    public class UnitOfWorkOperationInvoker : IOperationInvoker
    {
        private readonly IOperationInvoker _innerInvoker;

        public UnitOfWorkOperationInvoker(IOperationInvoker innerInvoker, OperationDescription description)
        {
            _innerInvoker = innerInvoker;
        }

        public object[] AllocateInputs()
        {
            return _innerInvoker.AllocateInputs();
        }

        public object Invoke(object instance, object[] inputs, out object[] outputs)
        {
            IUnitOfWork unitOfWork = null;

            try
            {
                unitOfWork = ObjectFactory.GetInstance<IUnitOfWork>();

                try
                {
                    var result = _innerInvoker.Invoke(instance, inputs, out outputs);
                    unitOfWork.Commit();
                    return result;
                }
                catch (Exception)
                {
                    unitOfWork.Rollback();
                    throw;
                }
            }
            finally
            {
                new HybridLifecycle().FindCache().DisposeAndClear();
            }
        }

        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        public bool IsSynchronous
        {
            get { return true; }
        }
    }
}